package nsga.population;

import java.util.ArrayList;
import java.util.List;

import abstractGA.chrom.Chrom;
import abstractGA.popu.Population;
import rulSeqGA.chromosome.RulSeqGAChrom;
import rulSeqGA.population.RulSeqGAPopu;

/**
 * NSGA种群类
 * @author nyc
 *
 */
public class NSRulSeqGAPopu extends NSGAPopu {
	
	// 产生空种群
	public NSRulSeqGAPopu() {
		super();
	}
	
	/**
	 * 
	 * @param crossoverNum
	 *            ：交叉的数目
	 */
	public void crossover(int crossoverNum) {
		// 种群大小
		int popSize = chroms.size();
		// 产生交叉的位置
		int chromLen = parameter.getChromLen();
		// 获取交叉概率
		float crossProb = parameter.getCrossProb();
		boolean isCrossed = false;
		// 随机对种群的两个个体进交叉操作
		for (int i = 0; i < popSize && popSize >= 2; i++) {
			// 随机判断第i个体是否参与交叉
			float draw = random.nextFloat();
			// 第i个体参与交叉
			if (Float.compare(draw,crossProb)<0) {
				Chrom srcChrom = chroms.get(i).copy();
				// 随机产生另一个交叉个体
				int otherIdx = random.nextInt(popSize);
				// 避免自身交叉
				while (otherIdx == i) {
					otherIdx = random.nextInt(popSize);
				}
				Chrom desChrom = chroms.get(otherIdx).copy();
				int crossPos = random.nextInt(chromLen);
				while (crossPos == 0) {// 防止第0位交叉，种群不变化
					crossPos = random.nextInt(chromLen);
				}
				List<List<StringBuffer>> tempChroms = doCrossover(srcChrom,
						desChrom, crossPos);
				//新编码的合法性检查和修复、染色体对应自由度实例列表和变更记录列表的处理
				((RulSeqGAChrom)srcChrom)
				.setCodes2(tempChroms.get(0),crossPos);
				//新编码的合法性检查和修复、染色体对应自由度实例列表和变更记录列表的处理
				((RulSeqGAChrom)desChrom)				
				.setCodes2(tempChroms.get(1),crossPos);			
				chroms.set(i, srcChrom);
/////////////////////////////				
				chroms.set(otherIdx, desChrom);
				isCrossed = true;
			}
		}
		if (isCrossed) {
			bestChroms.clear();
		}
	}
	
//	/**
//	 * 交配选择
//	 * @param chroms:染色体集合 
//	 * @param 返回：选中染色体下标的数组
//	 */
//	@Override
//	public int[] mutingChoose(List<Chrom> chroms) {
//		int size = chroms.size();
//		int[] idxs = new int[size];
//		ArrayList<ArrayList<Integer>> idxss = nondominatedSort(chroms);
//		for (int i = 0; i < size; i++) {
//			int idx1 = random.nextInt(size);
//			int idx2 = random.nextInt(size);
//			if (idx1 == idx2) {
//				idxs[i] = idx1;
//			} else {
//				int rank1 = getRank(idx1, idxss);
//				int rank2 = getRank(idx2, idxss);
//				if (rank1 < rank2) {
//					idxs[i] = idx1;
//				}
//				if (rank1 == rank2) {
//					ArrayList<Integer> frontIdxs = idxss.get(rank1);
//					int posIdx1 = frontIdxs.indexOf(idx1);
//					int posIdx2 = frontIdxs.indexOf(idx2);
//					List<Float> distances = getCrowdDistances(chroms, frontIdxs);
//
//					float dist1 = distances.get(posIdx1).floatValue();
//					float dist2 = distances.get(posIdx2).floatValue();
//
//					if (Float.compare(dist1, dist2) > 0) {
//						idxs[i] = idx1;
//					} else {
//						idxs[i] = idx2;
//					}
//				}
//				if (rank1 > rank2) {
//					idxs[i] = idx2;
//				}
//			}
//		}
//		return idxs;
//	}

//	/**
//	 * 非支配排序
//	 * @param chroms：染色体集
//	 * @return：按非支配等级排序后的染色体下标数组的数组，例如：
//	 * 等级0：[2,3]（pareto最优染色体下标）
//	 * 等级1：[0,1]
//	 */
//	public ArrayList<ArrayList<Integer>> nondominatedSort(List<Chrom> chroms) {
//		ArrayList<ArrayList<Integer>> idxss = new ArrayList<ArrayList<Integer>>();
//		ArrayList<Integer> rnk0Idxs = new ArrayList<Integer>();// 等级0（最好）的染色体下标
//		ArrayList<DominateInfo> dominateInfos = new ArrayList<DominateInfo>();
//		int size = chroms.size();
//		for (int i = 0; i < size; i++) {
//			Chrom chrom1 = chroms.get(i);
//			DominateInfo dominateInfo = new DominateInfo();
//			dominateInfo.idx = i;
//			float resTime1 = (Float) chrom1.getObjVals().get(0);		
//			float reltVal1 = (Float) chrom1.getObjVals().get(1);
//			float costVal1 = (Float) chrom1.getObjVals().get(2);	
//			for (int j = 0; j < size; j++) {
//				Chrom chrom2 = chroms.get(j);
//				if (chrom1 != chrom2) {
//					float resTime2 = (Float) chrom2.getObjVals().get(0);
//					float reltVal2 = (Float) chrom2.getObjVals().get(1);
//					float costVal2 = (Float) chrom2.getObjVals().get(2);
//					
//					if ((Float.compare(resTime2, resTime1) <= 0 &&  (Float.compare(costVal2, costVal1) < 0)&&(Float.compare(reltVal2, reltVal1) >= 0))// chrom2比chrom1优
//							|| (Float.compare(resTime2, resTime1) <= 0 && (Float.compare(costVal2, costVal1) <= 0)&&(Float.compare(reltVal2, reltVal1) > 0))
//							|| (Float.compare(resTime2, resTime1) < 0 && (Float.compare(costVal2, costVal1) <= 0)&&(Float.compare(reltVal2, reltVal1) >= 0))) {
//						dominateInfo.superiorNum += 1;
//					}
//
//					if ((Float.compare(resTime1, resTime2) <= 0 && (Float.compare(costVal1, costVal2) < 0)&&(Float.compare(reltVal1, reltVal2) >= 0))// chrom2比chrom1劣
//							|| (Float.compare(resTime1, resTime2) <= 0 && (Float.compare(costVal1, costVal2) <= 0)&&(Float.compare(reltVal1, reltVal2) > 0))
//							|| (Float.compare(resTime1, resTime2) < 0 && (Float.compare(costVal1, costVal2) <= 0)&&(Float.compare(reltVal1, reltVal2) >= 0))) {
//						dominateInfo.inferiorIdxs.add(new Integer(j));
//					}
//
//				}
//			}
//			if (dominateInfo.superiorNum == 0) {
//				rnk0Idxs.add(i);
//			}
//			dominateInfos.add(dominateInfo);
//		}
//		if (rnk0Idxs.size() > 0) {
//			idxss.add(rnk0Idxs);
//		}
//
//		ArrayList<Integer> curRnkIdxs = rnk0Idxs;
//		while (curRnkIdxs.size() > 0) {
//			ArrayList<Integer> nxtRnkIdxs = new ArrayList<Integer>();
//			for (Integer idx : curRnkIdxs) {
//				DominateInfo curInfo = dominateInfos.get(idx);
//				for (Integer inferiorIdx : curInfo.inferiorIdxs) {
//					DominateInfo inferiorInfo = dominateInfos.get(inferiorIdx);
//					inferiorInfo.superiorNum -= 1;
//					if (inferiorInfo.superiorNum == 0) {
//						nxtRnkIdxs.add(inferiorInfo.idx);
//					}
//				}
//			}
//			if (nxtRnkIdxs.size() > 0) {
//				idxss.add(nxtRnkIdxs);
//			}
//			curRnkIdxs = nxtRnkIdxs;
//		}
//		return idxss;
//	}
//
//	/**
//	 * 支配信息
//	 * @author nyc
//	 *
//	 */
//	protected class DominateInfo {
//		int idx = -1;// 本个体在种群中的下标
//		int superiorNum = 0;// 比本个体优的个体数目
//		List<Integer> inferiorIdxs = new ArrayList<Integer>();// 比本个体差的个体的下标
//
//	}
//
//	/**
//	 * 获取染色体的非支配等级
//	 * @param chromIdx：染色体在种群中的下标位置
//	 * @param idxss：按非支配等级排序后的染色体下标数组的数组
//	 * @return：chromIdx下标染色体对应的等级
//	 */
//	public int getRank(int chromIdx, ArrayList<ArrayList<Integer>> idxss) {
//		int rank = -1;
//		int rankNum = idxss.size();
//
//		for (int i = 0; i < rankNum; i++) {
//
//			int chromNum = idxss.get(i).size();
//			int tempChromIdx = -1;
//			boolean found = false;
//			for (int j = 0; j < chromNum; j++) {
//				tempChromIdx = idxss.get(i).get(j);
//				if (tempChromIdx == chromIdx) {
//					found = true;
//					break;
//				}
//			}
//			if (found) {
//				rank = i;
//				break;
//			}
//		}
//
//		return rank;
//	}
//
//	/**
//	 * 计算pareto前沿上各个染色体对应的拥塞距离
//	 * @param chroms:染色体集合（可能是种群也可能是两个种群的合集）
//	 * @param frontIdxs：前沿上染色体在染色体集chroms中的下标
//	 * @return：前沿上每个染色体对应的拥塞距离
//	 */
//	public List<Float> getCrowdDistances(List<Chrom> chroms,
//			ArrayList<Integer> frontIdxs) {
//		List<Float> crowdDistances = new ArrayList<Float>();
//		int size = frontIdxs.size();
//
//		if (size == 1) {
//			crowdDistances.add(new Float(Float.MAX_VALUE / 1000f));
//		}
//		if (size == 2) {
//			crowdDistances.add(new Float(Float.MAX_VALUE / 1000f));
//			crowdDistances.add(new Float(Float.MAX_VALUE / 1000f));
//		}
//
//		if (size > 2) {
//			for (int i = 0; i < size; i++) {
//				crowdDistances.add(new Float(0f));
//			}
//			for (int k = 1; k <= 3; k++) {
//				List<Integer> sortByFstObj = sortByObjVal(chroms, frontIdxs, k);				
//				
//				int idxOfMinVal = sortByFstObj.get(0);
//				int idxOfMaxVal = sortByFstObj.get(size - 1);
//				Object minVal = chroms.get(idxOfMinVal).getObjVals().get(k - 1);
//				Object maxVal = chroms.get(idxOfMaxVal).getObjVals().get(k - 1);
//
//				int idxInfrontIdxs = frontIdxs.indexOf(idxOfMinVal);			
//				float curVal = crowdDistances.get(idxInfrontIdxs).floatValue();
//				crowdDistances.set(idxInfrontIdxs, curVal + Float.MAX_VALUE
//						/ 1000f);
//				idxInfrontIdxs = frontIdxs.indexOf(idxOfMaxVal);
//				curVal = crowdDistances.get(idxInfrontIdxs).floatValue();
//				crowdDistances.set(idxInfrontIdxs, curVal + Float.MAX_VALUE
//						/ 1000f);
//
//				int idx1, idx2 = -1;
//
//				for (int j = 1; j < size - 1; j++) {
//					idx1 = frontIdxs.indexOf(sortByFstObj.get(j - 1));
//					idx2 = frontIdxs.indexOf(sortByFstObj.get(j + 1));
//					idxInfrontIdxs = frontIdxs.indexOf(sortByFstObj.get(j));
//					float curCrowDist = crowdDistances.get(idxInfrontIdxs);
//									
//					float maxFloatVal = ((Float) maxVal).floatValue();
//					float minFloatVal = ((Float) minVal).floatValue();
//					float obj1Val = (Float) chroms.get(idx1).getObjVals().get(k - 1);
//					float obj2Val = (Float) chroms.get(idx2).getObjVals().get(k - 1);
//
//					if (Float.compare(maxFloatVal, minFloatVal) == 0) {
//						crowdDistances.set(idxInfrontIdxs, 0f);
//					} else {
//						crowdDistances.set(idxInfrontIdxs,
//								curCrowDist + (obj2Val - obj1Val) / (maxFloatVal - minFloatVal));
//					}
//					
//				}
//			}
//		}
//
//		return crowdDistances;
//	}
//
//	/**
//	 * 按指定目标对前沿上的染色体进行排序
//	 * @param chroms：染色体
//	 * @param frontIdxs：前沿上染色体在染色体集chroms中的下标
//	 * @param whichObj：按哪一个目标进行排序 
//	 * @return
//	 */
//	public List<Integer> sortByObjVal(List<Chrom> chroms, ArrayList<Integer> frontIdxs, int whichObj) {
//		List<Integer> sortResults = new ArrayList<Integer>();
//		for (Integer fronIdx : frontIdxs) {
//			sortResults.add(fronIdx);
//		}
//
//		int size = sortResults.size();
//		for (int i = 0; i < size; i++) {
//			int m = sortResults.get(i);
//			Chrom chrom1 = chroms.get(m);
//			Object objVal1 = chrom1.getObjVals().get(whichObj - 1);
//			int idxOfMinVal = i;
//			for (int j = i + 1; j < size; j++) {
//				int n = sortResults.get(j);
//				Chrom chrom2 = chroms.get(n);
//				Object objVal2 = chrom2.getObjVals().get(whichObj - 1);
//				float obj1FloatVal = ((Float) objVal1).floatValue();
//				float obj2FloatVal = ((Float) objVal2).floatValue();
//				if (Float.compare(obj1FloatVal, obj2FloatVal) > 0) {
//					idxOfMinVal = j;
//					objVal1 = objVal2;
//				}
//			}
//			int temp = sortResults.get(i);
//			sortResults.set(i, sortResults.get(idxOfMinVal));
//			sortResults.set(idxOfMinVal, temp);
//
//		}
//		return sortResults;
//	}

//	@Override
//	/**
//	 * 环境选择
//	 * @param tempPopu：临时种群
//	 * @return：环境选择后的种群
//	 */
//	public Population envSelect(Population tempPopu) {
//		Population nxtPopu = copy();
//		int popuSize = chroms.size();
//		int tempPopuSize=tempPopu.getChroms().size();
//		if (popuSize <= 0 || popuSize != tempPopuSize) {
//			return nxtPopu;
//		}	
//		nxtPopu.add(tempPopu.getChroms());
//		ArrayList<ArrayList<Integer>> idxss = nondominatedSort(nxtPopu
//				.getChroms());
//		ArrayList<Chrom> selChroms = new ArrayList<Chrom>();
//		int i = 0;
//		ArrayList<Integer> frontIdxs = idxss.get(i);
//		int frontSize = frontIdxs.size();
//		int selSize = 0;
//		while (selSize + frontSize <= popuSize) {
//			for (Integer frontIdx : frontIdxs) {
//				selChroms.add(nxtPopu.getChroms().get(frontIdx).copy());
//			}
//			selSize = selChroms.size();
//			i += 1;
//			if (i < idxss.size()) {
//				frontIdxs = idxss.get(i);
//				frontSize = frontIdxs.size();
//			} else {
//				break;
//			}
//		}
//		selSize = selChroms.size();
//		if (selSize < popuSize && selSize + frontSize > popuSize) {
//			List<Float> dists = getCrowdDistances(nxtPopu.getChroms(),
//					frontIdxs);
//			ArrayList<Integer> sortedIdxs = publeSort(dists, frontIdxs);
//			int len = popuSize - selSize;
//			for (int k = 0; k < len; k++) {
//				int selIdx = sortedIdxs.get(k);
//				selChroms.add(nxtPopu.getChroms().get(selIdx));
//			}
//
//		}
//		nxtPopu.getChroms().clear();
//		nxtPopu.setChroms(selChroms);
//		return nxtPopu;
//	}

//	/**
//	 * 按拥塞距离对前沿上各个体进行排序
//	 * @param dists：拥塞距离
//	 * @param frontIdxs：前沿上各染色体的下标
//	 * @return：按拥塞距离从大到小的顺序排好序后的前沿上染色体的下标数组
//	 */
//	public ArrayList<Integer> publeSort(List<Float> dists,
//			ArrayList<Integer> frontIdxs) {
//		ArrayList<Integer> sortedIdxs = new ArrayList<Integer>();
//		for (Integer frontIdx : frontIdxs) {
//			sortedIdxs.add(frontIdx);
//		}
//
//		int size = dists.size();
//		for (int i = 0; i < size; i++) {
//			float dist1 = dists.get(i).floatValue();
//			int idxOfMaxVal = i;
//			for (int j = i + 1; j < size; j++) {
//				float dist2 = dists.get(j).floatValue();
//				if (Float.compare(dist1, dist2) < 0) {
//					dist1 = dist2;
//					idxOfMaxVal = j;
//				}
//			}
//			if (idxOfMaxVal != i) {
//				float temp = dists.get(i);
//				dists.set(i, dists.get(idxOfMaxVal));
//				dists.set(idxOfMaxVal, temp);
//				int tempInt = sortedIdxs.get(i);
//				sortedIdxs.set(i, sortedIdxs.get(idxOfMaxVal));
//				sortedIdxs.set(idxOfMaxVal, tempInt);
//			}
//
//		}
//
//		return sortedIdxs;
//	}

//	@Override
//	/**
//	 * 获取pareto最优染色体集
//	 */
//	public List<Chrom> getBestChroms() {	
//		if (bestChroms.size() == 0) {
//			if (chroms.size() > 0) {
//				// 非支配排序
//				ArrayList<ArrayList<Integer>> idxss = nondominatedSort(chroms);
//				ArrayList<Integer> idxs = idxss.get(0);
//				for (Integer idx : idxs) {
//					bestChroms.add(chroms.get(idx).copy());				
//				}
//			}
//		}		
//		return bestChroms;
//	}

	
	@Override
	//种群复制
	public Population copy() {
		Population newPopu = new NSRulSeqGAPopu();
		List<Chrom> newBestChroms = new ArrayList<Chrom>();
		for (Chrom bestChrom : bestChroms) {
			newBestChroms.add(bestChrom.copy());
		}
		newPopu.setBestChroms(newBestChroms);
		// 复制种群中的染色体
		for (int i = 0; i < chroms.size(); i++) {
			Chrom tmpChrom = chroms.get(i);
			newPopu.getChroms().add(tmpChrom.copy());
		}
		newPopu.setRandom(random);

		newPopu.setParameter(parameter);
		return newPopu;
	}
	
}
